using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using DSEngine.Core;
using DSEngine.Stage;

namespace DSEngine.Sprite
{
    public class SpDrawableObject : SpExtendObject
    {
        public SpDrawableObject(Layout layout)
        {
            this.Color = Color.White;
            this.Alpha = 1f;
            this.Effect = SpriteEffects.None;
            this.Parent = layout;
        }

        public Layout Parent { get; set; }
        public Color Color { get; set; }
        protected SpTexture curTexture;
        public virtual SpTexture Texture
        {
            get
            {
                return curTexture;
            }
            set
            {
                curTexture = value;
                this.Width = curTexture.Width * this.Scale.X;
                this.Height = curTexture.Height * this.Scale.Y;
                this.Source = new Rectangle(0, 0, (int)this.Width, (int)this.Height);
            }
        }
        private Vector2 _center;
        public virtual Vector2 Center
        {
            get
            {
                if (this.Texture == null)
                {
                    return default(Vector2);
                }
                return this.Position + new Vector2(this.Texture.Width * this.Scale.X / 2, this.Texture.Height * this.Scale.Y / 2);
            }
            set
            {
                Vector2 v = value;
                _center = v;
                v = v - new Vector2(this.Texture.Width * this.Scale.X / 2, this.Texture.Height * this.Scale.Y / 2);
                this.Position = v;
                
            }
        }
        
        public Rectangle Source { get; set; }
       
        public SpriteEffects Effect { get; set; }
        public override void Dispose()
        {
            if (this.Texture != null)
                this.Texture.Dispose();
            base.Dispose();
        }
        protected override List<BoundingBox> UpdateBoundingBox(GameTime gameTime)
        {
            List<BoundingBox> bb = new List<BoundingBox>();
            if (this.Texture != null)
            {
                Vector2 min = this.Parent.Position + this.Position;
                Vector2 max = this.Parent.Position + this.Position + new Vector2(this.Width , this.Height );
                bb.Add(
                    new BoundingBox(
                        new Vector3(min, 0),
                        new Vector3(max, 0)));
            }
            return bb;
        }
        protected override void InnerDraw(GameTime gt)
        {
            base.InnerDraw(gt);
            if (this.Texture != null)
            {
                DrawObject();
            }
        }
        public virtual void DrawObject(SpriteBatch sb)
        {
            if (Texture != null)
            {
                float alpha = this.Alpha > this.Parent.Alpha ? this.Parent.Alpha : this.Alpha;
                Color alphaColor = Color.Multiply(this.Color, alpha);
                sb.Draw(
                    Texture.Texture,
                    this.Position + new Vector2(this.Width / 2, this.Height / 2),
                    this.Source,
                    alphaColor,
                    this.Rotation,
                    new Vector2(Texture.Width / 2, Texture.Height / 2),
                    this.Scale,
                    this.Effect,
                    1);
            }
        }
        public override float Width
        {
            get
            {
                return base.Width * this.Scale.X;
            }
            set
            {
                base.Width = value;
                if (this.Texture != null)
                {
                    Vector2 v = this.Scale;
                    v.X = base.Width / this.Texture.Width;
                    this.Scale = v;
                }
            }
        }
        public override float Height
        {
            get
            {
                return base.Height * this.Scale.Y;
            }
            set
            {
                base.Height = value; 
                if (this.Texture != null)
                {
                    Vector2 v = this.Scale;
                    v.Y = base.Height / this.Texture.Height;
                    this.Scale = v;
                }
            }
        }
        public void DrawObject()
        {
            DrawObject(this.Parent.SpriteBatch);
        }

        new public void Draw(Microsoft.Xna.Framework.GameTime gameTime)
        {
            if (Visible)
            {
                InnerDraw(gameTime);
            }
        }
        new public void Update(Microsoft.Xna.Framework.GameTime gameTime)
        {
            if (Enable)
            {
                boundingBox = UpdateBoundingBox(gameTime);
                InnerUpdate(gameTime);
            }
        }
    }
}
